import { ConnectionData, Connection } from "/@/components/types";

export function useConnection() {
  let connecitonData: ConnectionData = {};
  function isUnExcept(exceptId, id) {
    if (Array.isArray(exceptId)) {
      return exceptId.indexOf(id) === -1;
    } else {
      return exceptId !== id;
    }
  }
  function getNextExceptId(exceptId, id) {
    if (Array.isArray(exceptId)) {
      exceptId.push(id);
      return exceptId;
    }
    return id;
  }
  const connection: Connection = {
    getData() {
      return connecitonData;
    },
    getConnect(id) {
      return connecitonData[id];
    },
    clear() {
      connecitonData = {};
    },
    isConnect(id) {
      const conn = connecitonData[id];
      return conn && conn.length > 0;
    },
    connect(id, drag) {
      let conn = connecitonData[id];
      if (!conn) {
        conn = connecitonData[id] = [];
      }
      conn.push(drag);
    },
    /**
     * @param {String} id 要解除连接的元素的id
     * @param {String} targetId 要在连接数组中解除连接的元素的id
     */
    disConnect(id, targetId) {
      const conn = connecitonData[id];
      if (conn) {
        conn.forEach((drag, i) => {
          if (targetId) {
            if (targetId === drag.id) {
              conn.splice(i, 1);
              return false;
            }
          } else {
            connection.disConnect(drag.id, id);
          }
        });
      }
      if ((targetId && conn.length === 0) || !targetId) {
        delete connecitonData[id];
      }
    },
    startTogether(id, exceptId) {
      // console.log(id, exceptId);
      const conn = connecitonData[id];
      if (!conn) return;
      conn.forEach((drag) => {
        if (isUnExcept(exceptId, drag.id)) {
          //递归一起拖动连接的组件
          connection.startTogether(drag.id, getNextExceptId(exceptId, id));
          if (drag.start) {
            drag.startData = drag.start();
          }
        }
      });
    },
    moveTogether(id, options, exceptId) {
      const conn = connecitonData[id];
      if (!conn) return;
      conn.forEach((drag) => {
        if (isUnExcept(exceptId, drag.id)) {
          if (options.connectPoints && drag.extra && drag.extra.connectPositionIndex !== undefined) {
            const target = options.connectPoints[drag.extra.connectPositionIndex];
            options.x = target.x;
            options.y = target.y;
          } else {
            options.startData = drag.startData;
          }
          drag.move(options);
          connection.moveTogether(drag.id, options, getNextExceptId(exceptId, id));
        }
      });
    },
    endTogether(id, exceptId) {
      const conn = connecitonData[id];
      if (!conn) return;
      conn.forEach((drag) => {
        if (isUnExcept(exceptId, drag.id)) {
          drag.end && drag.end();
          connection.endTogether(drag.id, getNextExceptId(exceptId, id));
        }
      });
    },
  };
  return connection;
}
